/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package sysno2signature;

import cz.mzk.oai.metadataRepository.tools.CannotReadDirectoryException;
import cz.mzk.oai.metadataRepository.tools.FileTools;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;

/**
 *
 * @author Martin Rehanek, Martin.Rehanek@gmail.com
 */
public class FileRenamer {

    private File dir;
    private List<String> notFoundSysnos;
    private List<String> foundSysnos;
    private Map<File, String> notProcessedFiles;
    private static final String FORMAT_UNKNOWN = "unknown";
    private static final String FORMAT_MASTER = "master";
    private static final String FORMAT_TEI = "tei";

    public FileRenamer(File dir) {
        if (dir == null) {
            throw new NullPointerException("dir");
        }
        String filename = dir.getAbsolutePath();
        if (!dir.isDirectory()) {
            throw new IllegalArgumentException("'" + filename + "' is not directory");
        }
        if (!dir.canRead()) {
            throw new IllegalArgumentException("cannot read directory '" + filename + "'");
        }
        this.dir = dir;
        notFoundSysnos = new ArrayList<String>();
        foundSysnos = new ArrayList<String>();
        notProcessedFiles = new HashMap<File, String>();
    }

    public void analyze(Converter converter) throws CannotReadDirectoryException {
        analyzeAndRename(converter, false, false);
    }

    public void rename(Converter converter) throws CannotReadDirectoryException {
        analyzeAndRename(converter, true, false);
    }

    private void analyzeAndRename(Converter converter, boolean rename, boolean verbose) throws CannotReadDirectoryException {
        //List<String> fileNames = Tools.readAbsoluteFilenames(dir);
        List<File> files = FileTools.readFiles(dir);
        for (File file : files) {
            //System.out.println(file.getAbsolutePath());
            //System.out.println(file.getName());
            String[] parsedFile = file.getName().split("\\.");
            if (parsedFile.length != 2) {
                notProcessedFiles.put(file, "incorrect file name");
            } else {//file in form 'name.suffix'
                String sysno = parsedFile[0];
                //System.out.println("sysno:" + sysno);
                String suffix = parsedFile[1];
                //System.out.println("suffix:" + suffix);
                if (!"xml".equals(suffix)) {
                    notProcessedFiles.put(file, "suffix differs from 'xml'");
                } else {//file in form 'name.xml'
                    String signature = converter.convertSysno(sysno);
                    if (signature == null) {
                        notFoundSysnos.add(sysno);
                    } else {//sysno found
                        foundSysnos.add(sysno);
                        String format = determineMetadataFormat(file);
                        //TODO: pripadne validovat, pridat schema atd.
                        System.out.println(file.getName() + ": " + format);
                        String newName = signature + "." + format + ".xml";
                        if (rename) {
                            File newFile = new File(dir.getAbsolutePath() + File.separator + newName);
                            System.out.println("renaming '" + file.getName() + "' to " + newName);
                            FileTools.moveFile(file, newFile);
                        }
                    }
                }
            }
        }

        System.out.println("Files: " + files.size());

        System.out.println("Skipped files: " + notProcessedFiles.size());
        if (verbose) {
            System.out.println("--------------------");
            for (File file : notProcessedFiles.keySet()) {
                System.out.println(file.getName() + " " + notProcessedFiles.get(file));
            }
        }
        System.out.println("Found sysnos: " + foundSysnos.size());
        if (verbose) {
            System.out.println("-------------");
            for (String sysno : foundSysnos) {
                System.out.println(sysno);
            }
        }
        System.out.println("Unknown sysnos: " + notFoundSysnos.size());
        if (verbose) {
            System.out.println("-----------------");
            for (String sysno : notFoundSysnos) {
                System.out.println(sysno);
            }
        }
    }

    private String determineMetadataFormat(File file) {
        try {
            Document doc = FileTools.loadDocument(file);
            Element root = doc.getRootElement();
            String rootName = root.getName();
            if ("TEI.2".equals(rootName)) {
                return FORMAT_MASTER;
            } else if ("TEI".equals(rootName)) {
                return FORMAT_TEI;
            } else {
                return FORMAT_UNKNOWN;
            }
        } catch (FileNotFoundException ex) {
            System.err.println("file '" + file.getAbsolutePath() + "' not found");
            return FORMAT_UNKNOWN;
        } catch (DocumentException ex) {
            //ex.printStackTrace();
            System.err.println("Error parsing xml file '" + file.getAbsolutePath() + "'");
            System.err.println(ex.getMessage());
            return FORMAT_UNKNOWN;
        }
    }
}
